#include "../include/mysqlPool.h"
#include "../include/conf_reader.h"
#include <mysql_driver.h>
#include <ctime>
mysqlPool::mysqlPool()
{
    conf_reader * reader=conf_reader::get_conf_reader_instance();
    sql::mysql::MySQL_Driver *driver=sql::mysql::get_mysql_driver_instance();
    //将一系列信息读取下来
    this->pool_size=std::atoi(reader->get_value_from_key("mysqlPoolSize","5"));
    this->hostName=reader->get_value_from_key("mysqlIpPort","192.168.174.139:3306");
    hostName="tcp://"+hostName;
    this->schema=reader->get_value_from_key("mysqlSchema","chat_user");
    this->userName=reader->get_value_from_key("userName","root");
    this->passwd=reader->get_value_from_key("passwd","Root1234!");
    //sql::SQLString url=url;
    
    for(int i=0;i<pool_size;++i){
        try{
            std::shared_ptr<mysqlConnection> s_p=std::shared_ptr<mysqlConnection>(new mysqlConnection(driver->connect(hostName,userName,passwd)));
            s_p->_con->setSchema(schema);
            s_p->keep_alive();
            this->_pool.push(s_p);
        }catch(sql::SQLException &e){
            std::cout<<"建立mysql连接失败："<<e.what();
            
        }
    }
    std::cout<<"成功建立mysql 连接"<<std::endl;
    this->stop_flag=RUNNING;
    _thread=std::thread([this](){
        //引入条件变量即可解决
        //std::lock_guard<std::mutex> l_g(mtx);
        std::unique_lock<std::mutex> u_l(mtx);
        while(1){
            cond_var.wait_for(u_l,std::chrono::hours(2),[this](){
                return this->stop_flag==STOP;       //如果被提前唤醒，那么就判断谓词，如果返回true,往下走，返回false ,继续剩余时间等待
            });
            if(this->stop_flag==STOP){
                break;
            }
            int now_size=this->_pool.size();    //获取当前大小
            for(int i=0;i<now_size;++i){
                auto item=_pool.front();
                item->keep_alive(); 
                _pool.pop();    //首部弹出
                _pool.push(item);   //尾部插入
            }
            std::cout<<"成功触发一次mysql的心跳发射"<<std::endl;

        }


    });

}

std::shared_ptr<mysqlConnection> mysqlPool::get_con()
{
    std::lock_guard<std::mutex> l_g(mtx);
    if(_pool.size()){
        
        std::shared_ptr<mysqlConnection> s_p=_pool.front();
        _pool.pop();
        return s_p;
    }else{
        

        //可能就不够了，那么可以考虑去创建并获取
        sql::mysql::MySQL_Driver *driver=sql::mysql::get_mysql_driver_instance();
        std::shared_ptr<mysqlConnection> s_p;
        s_p=std::shared_ptr<mysqlConnection>(new mysqlConnection(driver->connect(hostName,userName,passwd)));
        ++pool_size;
        time_t t=time(NULL);

        std::cout<<"当前时间："<<std::ctime(&t)<<"mysql con连接不够用，此时增大到"<<pool_size<<"个连接"<<std::endl;
        return s_p;
    }
    
}

void mysqlPool::return_con(std::shared_ptr<mysqlConnection> &con)
{
    std::lock_guard<std::mutex> l_g(mtx);
    _pool.push(con);
    

   
}
